<?php
/**
 * Created by PhpStorm.
 * User: s.utkin
 * Date: 16.12.2014
 * Time: 14:12
 */

namespace Forms;


use Pinenut\Config;
use Pinenut\Form;

/**
 * Форма для авторизованных пользователей
 *
 * @package Forms
 */
abstract class FormAction extends \Action {
	protected static $isPublic = true;
	
	/**
	 * Имя класса-конфига формы
	 *
	 * @var string
	 */
	protected static $_formConfigClass = '';

	/**
	 * Экземпляр пришед
	 * @var Form
	 */
	protected $form = null;

	/**
	 * Pull-параметры
	 *
	 * @return array|NULL|\string[]
	 */
	public static function pullParams(){
		return ['identity', 'isPost', 'isAjax'];
	}

	/**
	 * Набор привелегий, по каждой из которых доступно действие
	 *
	 * @return array|NULL|string
	 */
	public function privileges()
	{
		return ['#authorized'];
	}

	/**
	 *
	 */
	protected function run()
	{
		$this->onBeginRun();

		$this->form = $this->buildForm();

		# Post-запрос
		if ($this->request->_isPost) {
			# Частичный запрос
			if ($this->request->isPartial && $this->request->_isAjax) {
				$this->onIsPartial();
				return;
			}

			# Провал валидации формы
			if (!$this->form->process($this->request->params())) {
				$this->onValidationFail();
				return;
			}

			$this->onFormProcess();
		}
		# Get-запрос
		else {
			$this->onGetRequest();
		}

		$this->onEndRun();
	}

	/**
	 * Строит класс формы
	 *
	 * @return Form
	 */
	protected function buildForm()
	{
		$sessionId = $this->getFormSessionId();
		$formId = $this->getFormId();
		$formConfig = $this->getFormConfig();
		$formAction = $this->getFormAction();
		
		if ($formAction) {
			$formConfig['htmlOptions']['action'] = $formAction;
		}
		
		$form = new Form($sessionId, $formId, $formConfig);
		return $form;
	}

	/**
	 * Возвращает параметр sessionId для инициализации формы
	 *
	 * @return string
	 */
	protected function getFormSessionId()
	{
		return $this->request->_identity;
	}

	/**
	 * Возвращает параметр formId для инициализации формы
	 *
	 * @return string
	 */
	protected function getFormId()
	{
		return $this->request->action;
	}

	/**
	 * Возвращает конфиг для инициализации формы
	 *
	 * @return array|null
	 * @throws \Exception
	 */
	protected function getFormConfig()
	{
		$formConfigClass = static::$_formConfigClass;

		if (empty($formConfigClass)) { // || !($formConfigClass instanceof Config) -- не пашет эта проверка
			throw new \Exception("Wrong form config class '$formConfigClass' (static::\$_formConfigClass)");
		}

		return $formConfigClass::get();
	}
	
	
	/**
	 * Строим адрес на обработчик формы, по умолчани текущее действие без пармаетров
	 */
	protected function getFormAction() {
		return $this->url($this->request->action);
	}

	# Хуки
	/**
	 * Запускается, когда пришел частичный ajax-запрос методом POST
	 *
	 * @throws \Exception
	 */
	protected function onIsPartial()
	{
		$this->form->process($this->request->params(), true);
		$this->response->content =  $this->form->render();
		$this->response->noRender(true);
	}

	/**
	 * Запускается, когда пришел POST запрос и валидация форма провалилась
	 */
	protected function onValidationFail()
	{
		$this->response->form = $this->form;
	}

	/**
	 * Запускается в начале экшена run до каких-либо действий
	 */
	protected function onBeginRun()
	{
		if ($this->request->_isPost) {
			$this->response->noCache(true);
		}
	}

	/**
	 * Запускается в конце экшена run
	 */
	protected function onEndRun()
	{

	}

	/**
	 * Запускается, если пришел GET-запрос
	 */
	protected function onGetRequest()
	{
		$this->response->form = $this->form;
	}

	/**
	 * Обработка успешно валидированой формы, при POST-запросе
	 */
	protected function onFormProcess()
	{

	}
}